package logic

import (
	"context"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"fmt"

	"laundry-service/app/client/internal/svc"
	"laundry-service/app/client/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type SafeRefundLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewSafeRefundLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SafeRefundLogic {
	return &SafeRefundLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *SafeRefundLogic) SafeRefund(req *types.SafeRefundReq) (resp *types.Reply, err error) {
	key := "A1B2C3D4E5F60708090A0B0C0D0E0F10"
	orderNum, err := decrypt(key, req.EncryptedOrderNum)
	if err != nil {
		return nil, err
	}

	order, err := l.svcCtx.Db.GetOrderByNumber(orderNum)
	if err != nil {
		return nil, err
	}

	order.State = -1

	t, e := CreateRefundTokenByOrder(l.svcCtx.Db, order)
	if e != nil {
		logx.Errorf("创建退款记录失败，订单ID: %d, 错误: %v", order.ID, e)
		return
	}

	refundLogic := NewOrderStNtfCallbackLogic(l.ctx, l.svcCtx)
	refundLogic.WXRefundFunc(order, t)
	return
}

func decrypt(key, ciphertext string) (string, error) {
	block, err := aes.NewCipher([]byte(key))
	if err != nil {
		return "", err
	}

	ciphertextBytes, err := base64.URLEncoding.DecodeString(ciphertext)
	if err != nil {
		return "", err
	}

	if len(ciphertextBytes) < aes.BlockSize {
		return "", fmt.Errorf("ciphertext too short")
	}

	iv := ciphertextBytes[:aes.BlockSize]
	ciphertextBytes = ciphertextBytes[aes.BlockSize:]

	stream := cipher.NewCFBDecrypter(block, iv)
	stream.XORKeyStream(ciphertextBytes, ciphertextBytes)

	return string(ciphertextBytes), nil
}
